package hikari.objects3d;

import com.gooddies.wiring.Wiring;
import hikari.gui.panels.particle.BoxEmitterEditorPanel;
import hikari.gui.panels.particle.CylinderEmitterEditorPanel;
import hikari.gui.panels.particle.Particle3dPanel;
import hikari.gui.panels.particle.RingEmitterEditorPanel;
import hikari.gui.panels.particle.SphereEmitterEditorPanel;
import hikari.hcomponents.HComponent;
import hikari.managers.Manager3D;
import hikari.persistence.file.FileSection;
import hikari.utils.Utils;
import java.io.IOException;
import java.util.List;
import org.swig.jirr.E_MATERIAL_TYPE;
import org.swig.jirr.IBillboardSceneNode;
import org.swig.jirr.IParticleBoxEmitter;
import org.swig.jirr.IParticleCylinderEmitter;
import org.swig.jirr.IParticleEmitter;
import org.swig.jirr.IParticlePointEmitter;
import org.swig.jirr.IParticleRingEmitter;
import org.swig.jirr.IParticleSphereEmitter;
import org.swig.jirr.IParticleSystemSceneNode;
import org.swig.jirr.ISceneManager;
import org.swig.jirr.ITexture;
import org.swig.jirr.ITriangleSelector;
import org.swig.jirr.MATERIAL_FLAG;
import org.swig.jirr.aabbox3df;
import org.swig.jirr.dimension2df;

/**
 * @author Dmitry
 */
public class Particle3dObject extends GeometricObject {

    private IParticleSystemSceneNode particleSystem;
    private static ITexture particleTexture;
    private IBillboardSceneNode particleSprite;

    public Particle3dObject(ISceneManager sceneManager) {
        super("Particle System", true);
        initObject(sceneManager);
    }

    private ITexture getParticleTexture() {
        if (particleTexture == null) {
            particleTexture = Wiring.getComponent(Utils.class).loadTextureFromResource("icons/particles.png");
        }
        return particleTexture;
    }

    @Override
    public aabbox3df getBoundingBox() {
        return particleSprite.getBoundingBoxConst();
    }

    private void initObject(ISceneManager sceneManager) {
        particleSystem = sceneManager.addParticleSystemSceneNode();
        particleSystem.setMaterialFlag(MATERIAL_FLAG.EMF_LIGHTING, false);
        particleSystem.getEmitter();
        final IParticleEmitter boxEmmiter = particleSystem.createPointEmitter();
        particleSystem.setParticlesAreGlobal(true);
        particleSystem.setEmitter(boxEmmiter);
        setMeshSceneNode(particleSystem);

        particleSprite = sceneManager.addBillboardSceneNode(particleSystem, new dimension2df(2f, 2f));
        particleSprite.setMaterialTexture(0, getParticleTexture());
        particleSprite.setMaterialType(E_MATERIAL_TYPE.TRANSPARENT_ALPHA_CHANNEL_REF);
        particleSprite.setMaterialFlag(MATERIAL_FLAG.EMF_LIGHTING, false);
        particleSprite.setMaterialFlag(MATERIAL_FLAG.EMF_USE_MIP_MAPS, false);
        particleSprite.setMaterialFlag(MATERIAL_FLAG.EMF_ZBUFFER, false);
        ((Manager3D) Wiring.getComponent(Manager3D.class)).addAlwaysVisibleBillboard(particleSprite);

        ITriangleSelector selector = sceneManager.createTriangleSelectorFromBoundingBox(particleSprite);
        particleSystem.setTriangleSelector(selector);
    }

    public IParticleSystemSceneNode getParticleSystem() {
        return particleSystem;
    }

    @Override
    public boolean onRemove() {
        ((Manager3D) Wiring.getComponent(Manager3D.class)).removeAlwaysVisibleBillboard(particleSprite);
        return true;
    }

    @Override
    public String objectType() {
        return "particle";
    }

    @Override
    public List<HComponent> getEditPanels() {
        List<HComponent> components = super.getEditPanels();
        components.add(Wiring.getComponent(Particle3dPanel.class).updateWith3dObject(this));
        return components;
    }

    @Override
    public void writeData(FileSection parentSection) throws IOException {
        super.writeData(parentSection);
        IParticleSystemSceneNode part = getParticleSystem();
        IParticleEmitter emitter = part.getEmitter();
        FileSection sect = parentSection.createNewSection("particleSetting");
        sect.writeVector("direction", emitter.getDirection());
        sect.writeInt("maxAngleDegr", emitter.getMaxAngleDegrees());
        sect.writeLong("maxLifeTime", emitter.getMaxLifeTime());
        sect.writeLong("maxPartPerSec", emitter.getMaxParticlesPerSecond());
        sect.writeSColor("maxStartColor", emitter.getMaxStartColor());
        sect.writeDimension2d("maxStartSize", emitter.getMaxStartSize());
        sect.writeLong("minLifeTime", emitter.getMinLifeTime());
        sect.writeLong("minPartPerSec", emitter.getMinParticlesPerSecond());
        sect.writeSColor("minStartColor", emitter.getMinStartColor());
        sect.writeDimension2d("minStartSize", emitter.getMinStartSize());
        String emitterType = "";
        if (emitter instanceof IParticleBoxEmitter) {
            emitterType = "boxEm";
            BoxEmitterEditorPanel.writeData(sect, emitter);
        } else if (emitter instanceof IParticleCylinderEmitter) {
            emitterType = "cylinderEm";
            CylinderEmitterEditorPanel.writeData(sect, emitter);
        } else if (emitter instanceof IParticleRingEmitter) {
            emitterType = "ringEm";
            RingEmitterEditorPanel.writeData(sect, emitter);
        } else if (emitter instanceof IParticleSphereEmitter) {
            emitterType = "sphereEm";
            SphereEmitterEditorPanel.writeData(sect, emitter);
        } else if (emitter instanceof IParticlePointEmitter) {
            emitterType = "pointEm";
        } else {
            throw new RuntimeException("Cannot save particle emitter of the type " + emitter.getClass().getCanonicalName());
        }
        sect.writeString("emitterType", emitterType);
        sect.close();
    }
}